
module OpenStudio

  class Dialog

    attr_reader :container

    def initialize(container, interface, hash)
      @container = container  # In subclasses @container must be created before calling add_callbacks    
      @interface = interface  # The dialog reports back to this object using:  @interface.report
      @hash = hash
    end

    def add_callbacks
      @container.web_dialog.add_action_callback("on_change_element") { |d, p| on_change_element(d, p) }
      @container.web_dialog.add_action_callback("on_cancel") { on_cancel }
      @container.web_dialog.set_on_close { cleanup }  # Close icon was clicked in the title bar; dialog is already closed at this point
    end

    def on_change_element(d, p)
      # problem here:  assumes value does not have any commas in it, need to just split off first one
      args = p.split(",")
      key = args[0]
      value = args[1]
      
      if (args.length > 2)
        puts "Dialog.on_change_element: web dialog element with commas passed in"
      end
      
      # Not sure if this is a good idea
      if (value == 'true')
        value = true
      elsif (value == 'false')
        value = false
      end

      if (value.nil?)
        @hash[key] = ""
      else
        @hash[key] = value
      end
    end

    def update
      @hash.keys.each { |key| set_element_value(key, @hash[key]) }
    end

    def set_element_value(name, value)

      # This method works even if no 'name' attribute has been set; apparently tagName is defaulted to the 'id' attribute.
      # NOTE:  This will not work correctly for a 'select-multiple' element which requires options to be set individually.
      if (name.nil?)
        puts "Dialog:  nil name passed to set_element_value"
      else
        value = value.to_s.gsub(/'/, "\\\\'")  # Must encode any single quotes so that a JavaScript error is avoided

        if (Plugin.platform == Platform_Windows)
          value.gsub!(/\n/, "\\n")  # Replace \n with \\n for JavaScript
        elsif (Sketchup.version.to_i < 7)
          # Mac SU6
          value.gsub!(/,/, "%comma%")  # Replace commas with tags for Mac (SU6 bug)
        else
          # Mac SU7
          value.gsub!(/\r\n/, "\\n")  # Replace \n with \\n for JavaScript

          # "Unfix" a workaround for a bug in SU6 that added an extra space character at the beginning of the string.
          # SU7 corrects that bug, but the Javascript workaround in Dialogs.js still clips the first character.
          value = ' ' + value
        end

        @container.execute_function("setElementValue('" + name + "', '" + value + "')")
      end
    end

    def set_select_options(name, values, text = nil)
      if (name.nil?)
        puts "Dialog:  nil name passed to set_select_options"
      else
        if (values.nil?)
          values = []
        end
        if (text.nil?)
          text = values
        end

        values_arg = ""
        text_arg = ""

        if (not values.empty?)
          for i in 0...values.length
            if (values[i].nil?)
              values[i] = ""
            else
              values[i] = values[i].gsub(/'/, "%apos%")  # Encode any single quotes so that a JavaScript error is avoided
              # NOTE:  In other places this was done successfully using "\\\\'", but that does not work here...
            end
            if (text[i].nil?)
              text[i] = ""
            else
              text[i] = text[i].gsub(/'/, "%apos%")  # Encode any single quotes so that a JavaScript error is avoided
            end
            values_arg += values[i] + ","
            text_arg += text[i] + ","
          end
          values_arg = values_arg[0...values_arg.length - 1]
          text_arg = text_arg[0...text_arg.length - 1]
        end

        if (Plugin.platform != Platform_Windows)
          values_arg = values_arg.gsub(/,/, "%comma%")
          text_arg = text_arg.gsub(/,/, "%comma%")
        end

        @container.execute_function("setSelectOptions('" + name + "', '" + values_arg + "', '" + text_arg + "')")
      end
    end

    def set_element_source(name, path)
      if (name.nil?)
        puts "Dialog:  nil name passed to set_element_source"
      else
        if (path.nil?)
          path = ""
        end
        @container.execute_function("setElementSource('" + name + "', '" + path + "')")
      end    
    end

    def get_element_value_by_id(id)
      # Does not work for checkboxes
      if (id.nil?)
        puts "Dialog: nil id passed to get_element_value_by_id"
        value = nil
      else 
        value = @container.web_dialog.get_element_value(id)
      end
      return(value)
    end
    
    def disable_element(name)
      if (name.nil?)
        puts "Dialog:  nil name passed to disable_element"
      else      
        @container.execute_function("disableElement('" + name + "')")
      end
    end

    def enable_element(name)
      if (name.nil?)
        puts "Dialog:  nil name passed to enable_element"
      else      
        @container.execute_function("enableElement('" + name + "')")
      end
    end

    def hide_element(name)
      if (name.nil?)
        puts "Dialog:  nil name passed to hide_element"
      else      
        @container.execute_function("hideElement('" + name + "')")
      end
    end

    def show_element(name)
      if (name.nil?)
        puts "Dialog:  nil name passed to show_element"
      else      
        @container.execute_function("showElement('" + name + "')")
      end
    end

    def mark_element(name)
      if (name.nil?)
        puts "Dialog:  nil name passed to mark_element"
      else      
        @container.execute_function("markElement('" + name + "')")
      end
    end

    def unmark_element(name)
      if (name.nil?)
        puts "Dialog:  nil name passed to unmark_element"
      else      
        @container.execute_function("unmarkElement('" + name + "')")
      end
    end
  end

end